﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domains;
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
using MATLABApp;
using Test2;
using Untitled1;
using matlabRetinx;
using matRetinx;

namespace ImageProcessing
{
    class MatlabOperations
    {
        public static ImageStructure[,] Retinex(matRetinx.retinx matlabClass, ImageStructure[,] image, double[] sigma, double[] weight)
        {
            MWNumericArray retinexImage = (MWNumericArray)matlabClass.GetRtinx((MWNumericArray)ImageTo3DArray(image), (MWNumericArray)sigma, (MWNumericArray)weight);

            return Array3DToImage((byte[, ,])retinexImage.ToArray(MWArrayComponent.Real));
        }

        public static ImageStructure[,] Gaussain1D(Class2 matlabClass, ImageStructure[,] image, double sigma)
        {
            MWNumericArray gImage = (MWNumericArray)matlabClass.Gauss1DFilter((MWNumericArray)ImageTo3DArray(image), sigma);
            return Array3DToImage((double[, ,])gImage.ToArray(MWArrayComponent.Real));
        }

        public static double[, ,] ImageTo3DArray(ImageStructure[,] image)
        {
            int height = image.GetLength(0);
            int width = image.GetLength(1);
            double[, ,] newImage = new double[height, width, 3];
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    newImage[i, j, 0] = image[i, j].R;
                    newImage[i, j, 1] = image[i, j].B;
                    newImage[i, j, 2] = image[i, j].G;
                }
            }
            return newImage;
        }

        public static ImageStructure[,] Array3DToImage(double[, ,] image)
        {
            int height = image.GetLength(0);
            int width = image.GetLength(1);
            ImageStructure[,] newImage = new ImageStructure[height, width];
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    newImage[i, j].R = (byte)image[i, j, 0];
                    newImage[i, j].G = (byte)image[i, j, 1];
                    newImage[i, j].B = (byte)image[i, j, 2];
                }
            }
            return newImage;
        }

        public static ImageStructure[,] Array3DToImage(byte[, ,] image)
        {
            int height = image.GetLength(0);
            int width = image.GetLength(1);
            ImageStructure[,] newImage = new ImageStructure[height, width];
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    newImage[i, j].R = image[i, j, 0];
                    newImage[i, j].G = image[i, j, 1];
                    newImage[i, j].B = image[i, j, 2];
                }
            }
            return newImage;
        }

        public static ImageStructure[,] LocalStatistics(matoper3.Class1 matlabClass, DImage image, int windowSize, float E, float K0, float K1, float K2)
        {
            double[,] red = null;
            FourierOperations.SeparateColors(ref red, ref red, ref red, image);
            MWNumericArray retinexImage = (MWNumericArray)matlabClass.ELocalEnhancementUsingStatistics((MWNumericArray)red, windowSize, E, K0, K1, K2);

            byte[,] bytered = (byte[,])retinexImage.ToArray(MWArrayComponent.Real);



            for (int i = 0; i < image.Height; i++)
            {
                for (int j = 0; j < image.Width; j++)
                {
                    red[i, j] = bytered[i, j];
                }
            }
            return FourierOperations.RecollectImage(red, red, red, PostProcessing.None);
        }
    }
}